<template>
   <div>
      <el-dialog v-model="prop.is.isShow" :title="prop.is.isAdd ? '添加菜单' : '编辑菜单'" :before-close="cancel">

         <el-form :model="roleForm" :rules="rules" ref="roleRef">
            <!-- 角色名称 -->
            <el-form-item label="角色名称" prop="rolename" :label-width="formLabelWidth">
               <el-input v-model="roleForm.rolename" autocomplete="off" />
            </el-form-item>

            <!-- 角色权限 -->
            <el-form-item label="角色权限" prop="tree" :label-width="formLabelWidth">
               <el-tree ref="treeRef" :data="store.getters['menu/getMenulist']" show-checkbox default-expand-all
                  node-key="id" highlight-current :props="{ label: 'title' }" check-strictly :default-checked-keys="arr" />
            </el-form-item>

            <!-- 状态 -->
            <el-form-item label="状态" :label-width="formLabelWidth">
               <el-switch v-model="roleForm.status" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ccc"
                  :active-value="1" :inactive-value="2" />
            </el-form-item>
         </el-form>

         <template #footer>
            <span class="dialog-footer">
               <el-button @click="cancel">取消</el-button>
               <el-button type="primary" @click="enter">确认</el-button>
            </span>
         </template>
      </el-dialog>
   </div>
</template>


<script lang='ts' setup>
//引入接收父组件传过来的数据 ->defineProps    响应式数据 ->reactive  这里是为了获取DOM节点 ->ref
import { defineProps, reactive, ref, defineExpose } from "vue";
//引入仓库 Vuex
import { useStore } from "vuex";
//引入element-plus 封装好的验证规则
import { FormRules, FormInstance, ElMessage, ElTree } from 'element-plus';
//引入编辑或添加接口->addOrEditRole  获取一条数据 ->roleInfo
import { addOrEditRole, roleInfo } from "../../request/api";


//=================数据================
//弹窗左侧文字宽度
const formLabelWidth = '120px';
//父组件传过来的数据
let prop: any = defineProps({
   is: Object
});
//创建仓库
const store = useStore();
//创建树形控件 ref 
const treeRef = ref<InstanceType<typeof ElTree>>();
//创建树形控件 回显数组
let arr = reactive([]);
//创建表单ref
const roleRef = ref<FormInstance>();
//创建表单数据
let roleForm = reactive({
   rolename: '',
   menus: '',
   status: 1
});
//自定义验证规则
const treeFun = (a: any, b: any, callback: any) => {
   if (treeRef.value!.getCheckedKeys().length == 0) {
      callback(new Error('请选择角色权限'));
   } else {
      callback();
   }
}

//表单验证规则
const rules = reactive<FormRules>({
   rolename: [
      { required: true, message: '请输入角色名称', trigger: 'blur' },
      { min: 2, max: 6, message: '长度应在2-6', trigger: 'blur' },
   ],
   tree: { validator: treeFun, trigger: 'change' }
});



//================事件=================
//获取菜单管理的数据 判断是否有值  防止多次获取
if (store.getters['menu/getMenulist'].length == 0) {
   store.dispatch('menu/changeMenuAction');
};
//点击取消事件
const cancel = () => {
   //关闭弹窗
   prop.is.isShow = false;
   //清空表单
   roleForm = reactive({
      rolename: '',
      menus: '',
      status: 1
   });
   //清空树形控件
   treeRef.value!.setCheckedKeys([]);
};
//点击确认事件
const enter = () => {
   //树形控件的值是数组 需要转换成字符串
   roleForm.menus = treeRef.value!.getCheckedKeys().join(',');
   //判断是添加  还是  编辑
   let url: string = prop.is.isAdd ? '/roleadd' : '/roleedit';

   //表单是否通过验证
   roleRef.value?.validate(async (val: boolean) => {
      //通过验证
      if (val) {
         let res: any = await addOrEditRole(url, roleForm);
         //判断是否添加成功
         if (res.code == 200) {
            //成功提示
            ElMessage.success(res.msg);
            //关闭弹窗
            cancel();
            //重新获取数据
            store.dispatch('role/changeRoleAction');
         } else {
            //失败提示
            ElMessage.error(res.msg);
         };
      };
   });
};
//数据回显 
const lookup = async (id: number) => {
   let res: any = await roleInfo({ id });
   if (res.code == 200) {
      //回显树形控件
      arr = res.list.menus.split(',');
      treeRef.value!.setCheckedKeys(arr);
      //回显数据
      Object.assign(roleForm, res.list, { id });

   } else {
      ElMessage.error('角色回显失败');
   };

};

//需要暴露出去 才能在父组件获取到
defineExpose({
   lookup
})
</script>


<style lang='less' scoped></style>